package com.yuwubao.uav.tool.controller;

import com.alibaba.fastjson.JSONObject;
import com.yuwubao.framework.bean.JsonResult;
import com.yuwubao.framework.bean.PageData;
import com.yuwubao.uav.tool.service.FrontService;
import com.yuwubao.uav.tool.util.StringUtil;
import io.swagger.annotations.ApiParam;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import java.util.*;

/**
 * Created by yangyu on 2017/11/2.
 */
@RestController
@RequestMapping("/front")
@CrossOrigin

public class ArticleSearchController {

    private final static Logger logger = LoggerFactory.getLogger(ArticleSearchController.class);

    @Autowired
    private TransportClient client;

    /**
     */
    @GetMapping("/article")
    public JsonResult query(
            @ApiParam(value = "当前页", required = true) @Min(1) @Length(max = 8) @NotEmpty @RequestParam("page") String page,
            @ApiParam(value = "当前页数量", required = true) @Min(10) @Length(max = 3) @NotEmpty @RequestParam("pageSize") String pageSize,
            @ApiParam(value = "搜索关键字") @RequestParam(value = "searchKey",required = false) String searchKey
    ){
        JsonResult result = new JsonResult();
        try {
            List<PageData> list = new ArrayList<>();

            // 构建布尔查询
            QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder(searchKey);
            queryBuilder.analyzer("ik_smart");
            queryBuilder.field("title").field("author").field("content");

            HighlightBuilder hiBuilder = new HighlightBuilder();
            hiBuilder.preTags("<span style=\"color:red\">");
            hiBuilder.postTags("</span>");
            hiBuilder.field("title").field("author").field("content");

            SearchRequestBuilder builder = this.client.prepareSearch("zk").highlighter(hiBuilder)
                    .setTypes("article")
                    .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                    .setQuery(queryBuilder)
                    .setExplain(true)
                    .setFrom(Integer.parseInt(page)-1)
                    .setSize(Integer.parseInt(pageSize));

            SearchResponse response = builder.get();

            PageData pageDataRe = null;
            JSONObject pageData = null;
            Map<String, HighlightField> Hresult = null;
            HighlightField titleField = null;
            HighlightField contentField = null;
            for(SearchHit hit:response.getHits()){
                pageDataRe = new PageData();

                pageData = (JSONObject)JSONObject.parse(hit.getSourceAsString());

                pageDataRe.put("author",pageData.get("author"));

                Hresult = hit.highlightFields();
                //从设定的高亮域中取得指定域
                titleField = Hresult.get("title");
                if (titleField != null) {
                    Text[] titleTexts = titleField.fragments();
                    String title = "";
                    for(Text text : titleTexts){
                        title += text;
                    }
                    pageDataRe.put("title",title);
                } else {
                    pageDataRe.put("title",pageData.get("title"));
                }
                contentField = Hresult.get("content");
                if (contentField != null) {
                    Text[] contentTexts = contentField.fragments();
                    String content = "";
                    for (Text text: contentTexts){
                        content += text;
                    }
                    pageDataRe.put("content",content);
                } else {
                    pageDataRe.put("content",pageData.get("content"));
                }
                pageDataRe.put("img",pageData.get("img"));
                pageDataRe.put("id",hit.getId());

                list.add(pageDataRe);
            }
            result.setResult(list);
            result.setSuccessful();
        } catch (Exception e) {
            logger.warn("站内搜索异常", e);
            result.setFailure("站内搜索异常");
        }

        return result;
    }



    /**
     *  创建索引
     * @return
     */
    @PostMapping("/addIndex")
    public JsonResult addIndex(@RequestParam(required = false, defaultValue = "zk") String index){
        JsonResult result = new JsonResult();
        try {
            CreateIndexResponse createIndexResponse = this.client.admin().indices().prepareCreate(index).get();
            boolean acknowledged = createIndexResponse.isAcknowledged();
            if (acknowledged) {
                result.setSuccessful();
            } else {
                result.setSuccessful();
            }
        } catch (Exception e) {
            logger.warn("创建失败", e);
            result.setSuccessful();
        }
        return result;
    }

    /**
     * 给索引增加mapping。
     */
    @PostMapping("/addMapping")
    public JsonResult addMapping(@RequestParam(required = false, defaultValue = "zk") String index,
                                 @RequestParam(required = false, defaultValue = "article") String typeName) {
        JsonResult result = new JsonResult();
        try {
            // 使用XContentBuilder创建Mapping
            XContentBuilder builder = XContentFactory.jsonBuilder()
                    .startObject()
                    .field("properties")
                    .startObject()
                    .field("title")
                    .startObject()
                    .field("analyzer","ik_max_word")
                    .field("type", "text")
                    .endObject()
                    .field("author")
                    .startObject()
                    .field("analyzer","ik_smart")
                    .field("type", "text")
                    .endObject()
                    .field("content")
                    .startObject()
                    .field("analyzer","ik_max_word")
                    .field("type", "text")
                    .endObject()
                    .field("img")
                    .startObject()
                    .field("analyzer","ik_max_word")
                    .field("type", "text")
                    .endObject()
                    .endObject()
                    .endObject();
            System.out.println(builder.string());
            PutMappingRequest mappingRequest = Requests.putMappingRequest(index).source(builder).type(typeName);
            this.client.admin().indices().putMapping(mappingRequest).actionGet();
            result.setSuccessful();
        } catch (Exception e) {
            logger.warn("创建失败", e);
            result.setFailure("创建失败");
        }
        return result;
    }

    /**
     * 删除索引
     *
     */
    //@DeleteMapping("/es/deleteIndex")
    @PostMapping("/deleteIndex")
    public JsonResult deleteIndex(@RequestParam(required = false, defaultValue = "zk") String index) {
        JsonResult result = new JsonResult();
        try {
            DeleteIndexResponse deleteIndexResponse = this.client.admin().indices().prepareDelete(index).get();
            boolean acknowledged = deleteIndexResponse.isAcknowledged();// true表示成功
            if (acknowledged) {
                result.setSuccessful();
            } else {
                result.setFailure("删除索引失败");
            }
        } catch (Exception e) {
            logger.warn("删除索引异常", e);
            result.setFailure("删除索引异常");
        }
        return result;
    }


    /**
     *  创建一个文档
     * @return
     */
    @PostMapping("/createDoc")
    public JsonResult createDoc(@RequestParam(required = false, defaultValue = "zk") String index,
                                @RequestParam("id") String id,
                                @RequestParam("title") String title,
                                @RequestParam("author") String author,
                                @RequestParam("img") String img,
                                @RequestParam("content") String content){
        JsonResult result = new JsonResult();
        try {
//            JSONObject jsonObject = new JSONObject();
//            jsonObject.put("id",id);
//            jsonObject.put("img",img);
//            jsonObject.put("title",title);
//            jsonObject.put("author",author);
//            jsonObject.put("content",content);

            XContentBuilder builder = XContentFactory.jsonBuilder()
                        .startObject()
                        .field("id", id)
                        .field("author", author)
                        .field("content", content)
                        .field("title", title)
                        .field("img", img)
                        .endObject();

            IndexResponse response = client.prepareIndex(index, "article").setSource(builder).get();

            logger.info("索引名称:" + response.getIndex() + "\n类型:" + response.getType()
                    + "\n文档ID:" + response.getId() + "\n当前实例状态:" + response.status());

        } catch (Exception e) {
            logger.warn("创建失败", e);
            result.setSuccessful();
        }
        return result;
    }

    /**
     * 删除一个文档
     */
    @PostMapping("/deleteDoc")
    public JsonResult deleteDoc(@RequestParam(required = false, defaultValue = "zk") String index,
                                @RequestParam("id") String id) {
        JsonResult result = new JsonResult();
        try {
            IndexResponse deleteResponse = client.prepareIndex(index, "article",id).get();

            logger.info("deleteResponse索引名称:" + deleteResponse.getIndex() + "\n deleteResponse类型:" + deleteResponse.getType()
                    + "\n deleteResponse文档ID:" + deleteResponse.getId() + "\n当前实例deleteResponse状态:" + deleteResponse.status());

        } catch (Exception e) {
            logger.warn("删除索引异常", e);
            result.setFailure("删除索引异常");
        }
        return result;
    }


    /**
     *  获取索引的一条数据
     * @return
     */
    @PostMapping("/getDoc")
    public JsonResult getDoc(
            @RequestParam(required = false, defaultValue = "zk") String index,
            @RequestParam("id") String id
    ){
        JsonResult result = new JsonResult();
        try {

            PageData pageData = new PageData();

            String str = this.client
                    .prepareGet()    // 准备进行get操作，此时还有真正地执行get操作。（与直接get的区别）
                    .setIndex(index)  // 要查询的
                    .setType("article")
                    .setId(id)
                    .get()
                    .getSourceAsString();
            if (StringUtil.isNotNvlOrBlank(str)) {
                JSONObject jsonObject = (JSONObject) JSONObject.parse(str);
                if (jsonObject != null) {
                    pageData = new PageData();
                    pageData.put("id",id);
                    pageData.put("dbId",jsonObject.get("dbId"));
                    pageData.put("title",jsonObject.get("title"));
                    pageData.put("author",jsonObject.get("author"));
                    pageData.put("content",jsonObject.get("content"));
                    pageData.put("img",jsonObject.get("img"));

                }

            }

            result.setResult(pageData);

//            result.setResult(this.client
//                    .prepareGet()    // 准备进行get操作，此时还有真正地执行get操作。（与直接get的区别）
//                    .setIndex(index)  // 要查询的
//                    .setType("article")
//                    .setId(id)
//                    .get()
//                    .getSourceAsString());

            result.setSuccessful();

        } catch (Exception e) {
            logger.warn("创建失败", e);
            result.setSuccessful();
        }
        return result;
    }






}
